#include "pointsgenerator.h"

#include "settings/settings.h"
#include "datamanager.h"
#include <cmath>
#include <iostream>
#include <map>

PointsGenerator* PointsGenerator::instance()
{
	static PointsGenerator c;
	return &c;
}
PointsGenerator::PointsGenerator()
{
	size = Settings::instance()->getSize();
	pointMap = new double *[size];
	for(int i=0;i<size;i++){
		pointMap[i] = new double[size];
	}
	connect(&time,SIGNAL(timeout()),this,SLOT(sPrepare()));
	connect(&fps,SIGNAL(timeout()),this,SLOT(sfps()));
	capts=0;
	lcaps=0;
}
void PointsGenerator::sPrepare()
{
	double point, max=0;
	int sx, sy;
	for(int x=0;x<size;x+=2){
		for(int y=0;y<size;y+=2){
			pointMap[x][y]=0;
			for(int k=0;k<Settings::instance()->getSourcesCount();++k){
				Settings::instance()->getSourcePosition(k,sx,sy);
				point = sqrt((x-sx)*(x-sx)+(y-sy)*(y-sy))-capts;
				point*=Settings::instance()->getFreq(k);
				point/=10;
				point+=Settings::instance()->getPhase(k);
				point = round(fmod(fabs(point), 6.28)*10)/10.0;
				pointMap[x][y] += Settings::instance()->getAmplitude(k) * DataManager::instance()->getSin(point);
				pointMap[x+1][y+1]=pointMap[x][y];
				pointMap[x][y+1]=pointMap[x][y];
				pointMap[x+1][y]=pointMap[x][y];
			}
			if(fabs(pointMap[x][y]) > max)
				max = fabs(pointMap[x][y]);
		}
	}
	capts++;
	emit onPointMap(pointMap,max);
}
void PointsGenerator::sfps()
{
	std::cout << "fps: " << capts-lcaps << std::endl;
	lcaps = capts;
}

void PointsGenerator::sStart()
{
	time.start(Settings::instance()->getInterval()*1000);
	fps.start(1000);
}
void PointsGenerator::sStop()
{
// 	std::cout << "ilość klatek: " << capts << std::endl;
	time.stop();
	fps.stop();
}

double**& PointsGenerator::getPointMap()
{
    return pointMap;
}

const int PointsGenerator::getSize()
{
    return size;
}
PointsGenerator::~PointsGenerator()
{
	disconnect(&time,SIGNAL(timeout()),this,SLOT(sPrepare()));
	disconnect(&fps,SIGNAL(timeout()),this,SLOT(sfps()));
}
void PointsGenerator::selectFrame(int frame)
{
    capts+=frame;
    sPrepare();
}
bool PointsGenerator::isStarted()
{
	return time.isActive();
}
